package cn.org.qary.controller.abelianymph.front;

import cn.org.qary.entity.AddressInfo;
import cn.org.qary.entity.CartRecord;
import cn.org.qary.entity.Product;
import cn.org.qary.entity.User;
import cn.org.qary.service.trait.abelianymph.CartService;
import cn.org.qary.service.trait.abelianymph.ProductService;
import cn.org.qary.service.trait.rking.AddressInfoService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import io.vavr.Tuple2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.stream.Collectors;

@Controller
@RequestMapping("cart")
public class CartController {

    @Autowired
    HttpSession session;

    @Autowired
    CartService cartService;

    @Autowired
    ProductService productService;

    @Autowired
    AddressInfoService addressInfoService;



    @RequestMapping("add")
    public String add(
            Integer productId,
            Integer amount
    ) {
        increase(productId, amount);
        return "redirect:/cart/display";
    }

    @RequestMapping("increase")
    @ResponseBody
    public Boolean increase(
            Integer productId,
            Integer amount
    ) {

        User user = ((User) session.getAttribute("user"));
        // 添加购物车之前先做检查，如果购物车中的商品存在，只需添加数量
        if (cartService.productIsExist(user.getId(), productId)) {
            CartRecord cartRecord = cartService.selectByCombineId(user.getId(), productId);
            cartRecord.setAmount(cartRecord.getAmount() + amount);
            return cartService.update(cartRecord);
        }
        else {
            CartRecord cartRecord = new CartRecord();
            cartRecord.setProductId(productId);
            cartRecord.setAmount(amount);
            cartRecord.setUserId(user.getId());
            return cartService.insert(cartRecord);
        }

    }

    @RequestMapping("reduce")
    @ResponseBody
    public Boolean reduce(
            Integer productId,
            Integer amount
    ) {

        User user = ((User) session.getAttribute("user"));
        // 添加购物车之前先做检查，如果购物车中的商品存在，只需减少数量
        if (cartService.productIsExist(user.getId(), productId)) {
            CartRecord cartRecord = cartService.selectByCombineId(user.getId(), productId);

            if (cartRecord.getAmount() - amount <= 0) {
                return cartService.delete(cartRecord.getId());
            }
            else {
                cartRecord.setAmount(cartRecord.getAmount() - amount);
                return cartService.update(cartRecord);
            }

        }
        else {
            CartRecord cartRecord = new CartRecord();
            cartRecord.setProductId(productId);
            cartRecord.setAmount(amount);
            cartRecord.setUserId(user.getId());
            return cartService.insert(cartRecord);

        }

    }

    @RequestMapping("set")
    @ResponseBody
    public Boolean set(
            Integer productId,
            Integer amount
    ) {
        User user = ((User) session.getAttribute("user"));
        System.out.println(productId);
        if (cartService.productIsExist(user.getId(), productId)) {
            CartRecord cartRecord = cartService.selectByCombineId(user.getId(), productId);
            cartRecord.setAmount(amount);
            return cartService.update(cartRecord);
        }

        return false;

    }

    @RequestMapping("total_price")
    @ResponseBody
    public Integer totalPrice() {
        User user = ((User) session.getAttribute("user"));
        Example example = new Example(CartRecord.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", user.getId());

        List<CartRecord> cartRecords = cartService.selectByCondition(example);
        Integer total = cartRecords.stream()
                .map(cr -> new Tuple2<>(productService.selectById(cr.getProductId()), cr))
                .map(t -> new Tuple2<>(t._1().getPrice(), t._2().getAmount()))
                .map(t -> Integer.parseInt(t._1()) * t._2())
                .reduce(0, Integer::sum);

        return total;
    }


    @RequestMapping("confirm_order")
    @ResponseBody
    public String confirmOrder(
            String arrayJsonString
    ) {
        User user = ((User) session.getAttribute("user"));
        JSONArray array = JSON.parseArray(arrayJsonString);
        List<Integer> productIdList = array.toJavaList(Integer.class);
        Example example = new Example(CartRecord.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", user.getId());
        criteria.andIn("productId", productIdList);

        List<CartRecord> cartRecordList = cartService.selectByCondition(example);

        List<Tuple2<Product, CartRecord>> tuple2List = cartRecordList.stream()
                .map(cr -> new Tuple2<>(productService.selectById(cr.getProductId()), cr))
                .collect(Collectors.toList());
        session.setAttribute("tuple2List", tuple2List);

        Integer totalPrice = tuple2List.stream()
                .map(t -> Integer.parseInt(t._1().getPrice()) * t._2().getAmount())
                .reduce(0, Integer::sum);
        session.setAttribute("totalPrice", totalPrice);

        Example addressInfoExample = new Example(AddressInfo.class);
        Example.Criteria addressInfoExampleCriteria = addressInfoExample.createCriteria();

        addressInfoExampleCriteria.andEqualTo("userId", user.getId());

        List<AddressInfo> addressInfoList = addressInfoService.selectByCondition(addressInfoExample);

        session.setAttribute("addressInfoList", addressInfoList);

        session.setAttribute("token", "token");

        return "submitpath.jsp";
    }

    @RequestMapping("display")
    public String display(Model model) {
        User user = ((User) session.getAttribute("user"));


        Example condition = new Example(CartRecord.class);
        Example.Criteria criteria = condition.createCriteria();
        criteria.andEqualTo("userId", user.getId());

        List<CartRecord> cartRecordList = cartService.selectByCondition(condition);

        model.addAttribute("cart_product_amount", cartRecordList.size());

        List<Tuple2<Product, CartRecord>> tuple2List =
                cartRecordList
                        .stream()
                        .map(cr -> new Tuple2<>(productService.selectById(cr.getProductId()), cr))
                        .collect(Collectors.toList());

        System.out.println(tuple2List);
        model.addAttribute("tuple2List", tuple2List);
        return "submit";
    }


}
